<?php

namespace Biz\model\activity;

use Biz\pockets\constInterface\ActivityInfo;
use Biz\service\activity\AllActivityInfo;
use Doraemon\pockets\datebase\BaseDbModel;

class LimitTimeRobbing extends BaseDbModel
{

    const _CONFIG_FILE_ = 'db_shop';

    const _CONFIG_SELECT_ = 'db_activity';

    const _DATABASE_ = 'shop_activity';

    const _TABLE_NAME = 'limit_time_robbing';

    const STATUS_NORMAL = 1;

    const STATUS_ONLY_SKU = 2;

    const STATUS_DEL = 9;


    public static function selectNoHappenedInfos($goods_ids)
    {
        $infos = self::select("*", [
            'goods_id' => $goods_ids,
            'end_time[>]' => date("Y-m-d H:i:s"),
            'status' => [
                self::STATUS_NORMAL,
                self::STATUS_ONLY_SKU
            ]
        ]);
        $robbing_ids = array_column($infos, "id");
        $robbingSkus = LimitTimeRobbingSku::getInfo([
            'robbing_id' => $robbing_ids
        ]);

        $returnRst = [];
        foreach ($robbingSkus as $robbingSku) {
            $returnRst[$robbingSku['robbing_id'] . "_" . $robbingSku['goods_id']][] = $robbingSku;
        }

        return $returnRst;

    }

    public static function getInfos($ids)
    {
        $RobbingInfos = self::select("*", [
            'id' => $ids,
            'status' => self::STATUS_NORMAL
        ]);
        if ($RobbingInfos) {
            return array_column($RobbingInfos, null, "id");
        } else {
            return [];
        }
    }

    public static function nextDateTime()
    {
        $nowDate = strtotime(date("Y-m-d"));

        $currHours = date('H');
        if ($currHours >= 9 && $currHours < 21) {
            $date_time_start = date("Y-m-d H:i:s", $nowDate + 86400 - 3600 * 3);
            $date_time_end = date("Y-m-d H:i:s", $nowDate + 86400 + 3600 * 9);
        } else if ($currHours < 9) {
            $date_time_start = date("Y-m-d H:i:s", $nowDate + 3600 * 9);
            $date_time_end = date("Y-m-d H:i:s", $nowDate + 3600 * 21);
        } else if ($currHours >= 21) {
            $date_time_start = date("Y-m-d H:i:s", $nowDate + 86400 + 3600 * 9);
            $date_time_end = date("Y-m-d H:i:s", $nowDate + 86400 + 3600 * 21);
        }

        return [
            $date_time_start,
            $date_time_end
        ];

    }

    public static function getInfo($start_time, $end_time, $goods_id)
    {
        return self::get("*", [
            'goods_id' => $goods_id,
            'start_time' => $start_time,
            'end_time' => $end_time,
            'status' => [
                self::STATUS_NORMAL,
                self::STATUS_ONLY_SKU
            ]
        ]);

    }

    public static function selectInfos($start_time, $end_time)
    {
        return self::select("*", [
            'start_time' => $start_time,
            'end_time' => $end_time,
            'status' => [
                self::STATUS_NORMAL,
                self::STATUS_ONLY_SKU
            ]
        ]);
    }

    public static function updateRobbing($data = [], $where = [])
    {
        return self::update($data, $where);
    }


    public static function getListByTime($where = [], $start_time = '', $end_time = '')
    {


        $map = [
            'status' => self::STATUS_NORMAL,
        ];

        $count = count(self::select('*', [
            'status' => self::STATUS_NORMAL,
            'GROUP' => [
                'start_time',
                'end_time',
            ]
        ]));

        if ($start_time && $end_time) {
            $map['start_time[<]'] = $start_time;
            $map['end_time[>]'] = $end_time;
        }

        if ($where) {
            $map = array_merge($map, $where);
        }

        $map['ORDER'] = [
            'start_time' => 'DESC',
            'end_time' => 'DESC',
        ];

        return [
            $count,
            self::select("*", $map)
        ];
    }

    public static function getFiledsByFilter($fields = [], $where = [])
    {

        $results = self::select($fields, $where);

        if (count($fields) == 1) {

            return array_map(function ($result) use ($fields) {
                return $result[$fields[0]];
            }, $results);
        } else {
            return $results;
        }

    }

    public static function saveTimeRobings($start_time, $end_time, $goods_id, $shop_id, $admin_id, $sku_stocks, $flashSaleId)
    {
        $robInfo = self::getInfo($start_time, $end_time, $goods_id);

        $robid = '';
        $stock = array_filter($sku_stocks, function ($stock) {
            return (boolean)$stock;
        });
        if ($robInfo) {
            $robid = $robInfo['id'];
            if (!$stock) {
                self::updateRobbing(['status' => self::STATUS_DEL], [
                    'start_time' => $start_time,
                    'end_time' => $end_time,
                    'goods_id' => $goods_id,
                ]);
                AllActivityInfo::admDelActivityByGoodsId($robid, ActivityInfo::ACTIVITY_TYPE_LIMIT_TIME_ROB, $goods_id, AllActivityInfo::ALL_ACTIVITY_TYPE_FLASH_SALE);
            }
        } else {
            if ($stock) {
                self::insert([
                    'flash_sale_id' => $flashSaleId,
                    'goods_id' => $goods_id,
                    'shop_id' => $shop_id,
                    'start_time' => $start_time,
                    'end_time' => $end_time,
                    'add_time' => date("Y-m-d H:i:s"),
                    'admin_id' => $admin_id,
                    'status' => self::STATUS_ONLY_SKU
                ]);
                $robid = self::id();
            }
        }

        if ($robid) {
            LimitTimeRobbingSku::saveRobingInfo($start_time, $end_time, $robid, $goods_id, $shop_id, $admin_id, $sku_stocks);

        }


    }

    public static function HappeningList($now_date)
    {
        $info = self::select("*", [
            'start_time[<]' => $now_date,
            'end_time[>]' => $now_date,
            'status' => self::STATUS_NORMAL,
            'ORDER' => [
                'start_time' => 'ASC'
            ]
        ]);

        return array_column($info, null, 'goods_id');


    }

    public static function TraitList()
    {
        $infos = self::select("*", [
            "start_time[>]" => date("Y-m-d H:i:s"),
            'status' => self::STATUS_NORMAL,
            'ORDER' => [
                'start_time' => 'ASC',
            ]
        ]);

        $rst = [];
        foreach ($infos as $info) {
            if (count($rst) <= 1) {
                $rst[$info['start_time'] . "_" . $info['end_time']][] = $info;
            } else {
                break;
            }
        }

        if ($rst) {
            return
                array_shift($rst);
        }

        return [];
    }

    /**
     *
     * 根据商品IDS获得未结束的活动 并且 活动sku库存大于零
     *
     * @param array $goods_ids 商品IDS
     * @return array $formatRst 以商品ID与时间区间聚合
     */
    public static function getNotOverList(array $goods_ids)
    {
        $now_datatime = date("Y-m-d H:i:s");

        $infos = self::select("*", [
            'goods_id' => $goods_ids,
            'end_time[>]' => $now_datatime,
            'status' => self::STATUS_NORMAL,
            'ORDER' => [
                'start_time' => 'ASC',
                'end_time' => 'ASC'
            ]
        ]);
        $robbing_ids = array_column($infos, 'id');
        $flash_sale_ids = empty($infos) ? [] : array_column($infos, 'flash_sale_id');
        $flash_sale_ids = empty($flash_sale_ids) ? [] : FlashSale::select(['id', 'type'], ['id' => $flash_sale_ids]);
        $flash_sale_map = empty($flash_sale_ids) ? [] : array_column($flash_sale_ids, 'type', 'id');

        $limitSkus = $robbing_ids ? LimitTimeRobbingSku::getInfosByRobID($robbing_ids, true) : [];

        $formatRst = [];

        foreach ($infos as $info) {
            $info['type'] = $flash_sale_map[$info['flash_sale_id']] ?? 0;
            $formatRst[$info['goods_id']][] = array_merge($info, [
                'sku_list' => isset($limitSkus[$info['id']]) ? $limitSkus[$info['id']] : null
            ]);
        }

        return $formatRst;
    }

    public static function getFlashSaleIngGoodsInfos($flashSaleId, $field = '*', $isMaster = false)
    {
        $funName = 'select';
        if ($isMaster) {
            $funName = 'select_master';
        }
        return self::$funName($field, [
            'flash_sale_id' => $flashSaleId,
            'status' => self::STATUS_NORMAL,
            'ORDER' => ['order' => 'ASC']
        ]);
    }

    public static function admSave($data, $adminuid)
    {
        $currentGoodsIds = [];
        foreach ($data['goods'] as &$datum) {
            $saveData = [
                'describe' => $datum['describe'],
                'order' => $datum['order'],
                'buy_price' => $datum['buy_price'],
                'buy_limit' => $datum['buy_limit'],
                'commission' => $datum['commission'],
                'start_time' => $datum['start_time'],
                'end_time' => $datum['end_time'],
                'admin_id' => $adminuid,
            ];
            $id = self::get('id', [
                'goods_id' => $datum['goods_id'],
                'flash_sale_id' => $data['flash_id'],
            ]);
            if ($id) {
                self::update(array_merge($saveData, [
                    'status' => self::STATUS_NORMAL,
                ]), ['id' => $id]);
            } else {
                self::insert(array_merge($saveData, [
                    'flash_sale_id' => $data['flash_id'],
                    'goods_id' => $datum['goods_id'],
                    'shop_id' => $datum['shop_id'],
                    'status' => self::STATUS_NORMAL,
                    'add_time' => date('Y-m-d H:i:s'),
                ]));
                $id = self::id();
            }
            $datum['robbing_id'] = $id;
            $currentGoodsIds[] = $datum['goods_id'];
        }
        $where['flash_sale_id'] = $data['flash_id'];
        if ($currentGoodsIds) {
            $where['goods_id[!]'] = $currentGoodsIds;
        }
        $robbingIds = self::select('id', $where);
        LimitTimeRobbingSku::update(['status' => LimitTimeRobbingSku::STATUS_DEL], ['robbing_id' => $robbingIds]);
        self::update(['status' => self::STATUS_DEL], $where);
        return $data;
    }
}